package de.xelerity.geolessi.servlet;

import java.io.IOException;
import java.io.OutputStream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.fasterxml.jackson.databind.ObjectMapper;
import de.xelerity.geolessi.srv.InfoProvider;
import de.xelerity.geolessi.srv.InfoProvider.HALTESTELLENINFOPROVIDER;
import de.xelerity.geolessi.srv.poi.HalteStellenGetterFacadeI;
import de.xelerity.geolessi.types.mixed.Koordinate;
import de.xelerity.geolessi.types.poi.HalteStelle;
import de.xelerity.geolessi.types.poi.HalteStellenListe;
import de.xelerity.helper.StringFunktionen;

public class GetHS extends HttpServlet {

	private static final long serialVersionUID = -8426968243904258759L;
	private static Log log = LogFactory.getLog(GetHS.class);

	private class WSInput {
		public Koordinate coord = new Koordinate();
		public long radius = -1;
		public long hstype = HalteStelle.HalteStelleTyp_ALLE;
		public double spanX = 0.0;
		public double spanY = 0.0;
	}

	private WSInput parseInput(HttpServletRequest request) throws Exception {
		if (request == null)
			throw new IllegalArgumentException("request==null");

		WSInput wsinput = new WSInput();

		String xpara = request.getParameter("x");
		if (StringFunktionen.isEmptyTrimed(xpara))
			throw new IllegalArgumentException("Invalid Parameter: 'x' para did not exists");

		String ypara = request.getParameter("y");
		if (StringFunktionen.isEmptyTrimed(ypara))
			throw new IllegalArgumentException("Invalid Parameter: 'y' para did not exists");

		wsinput.coord = new Koordinate(ypara, xpara);

		if (!wsinput.coord.isValid())
			throw new IllegalArgumentException("Invalid Parameter: invalid x,y coordinates");

		String hs = request.getParameter("hstype");
		if (StringFunktionen.isEmptyTrimed(hs)) {
			wsinput.hstype = HalteStelle.HalteStelleTyp_ALLE;
		} else {
			if (!hs.trim().matches("[0-9]+"))
				throw new IllegalArgumentException("Invalid Parameter: 'hstype' para is not a number");

			wsinput.hstype = Long.parseLong(hs.trim());
		}

		String r = request.getParameter("r");
		if (!StringFunktionen.isEmptyTrimed(r)) {

			if (!r.trim().matches("[0-9]+")) {
				throw new IllegalArgumentException("Invalid Parameter: 'r' para is not a number");
			}
			wsinput.radius = Long.parseLong(r);
		}

		String spanX = request.getParameter("spanx");

		if (!StringFunktionen.isEmptyTrimed(spanX)) {
			spanX = spanX.replaceAll(",", ".").replaceAll("\\s", "");
			if (!spanX.trim().matches("^(\\+|-)?[0-9]+(\\.[0-9]+)?")) {
				throw new IllegalArgumentException("Invalid Parameter: 'spanx' para is not a double");
			}
			wsinput.spanX = Math.abs(Double.parseDouble(spanX));
		}

		String spanY = request.getParameter("spany");

		if (!StringFunktionen.isEmptyTrimed(spanY)) {
			spanY = spanY.replaceAll(",", ".").replaceAll("\\s", "");
			if (!spanY.trim().matches("^(\\+|-)?[0-9]+(\\.[0-9]+)?")) {
				throw new IllegalArgumentException("Invalid Parameter: 'spany' para is not a double");
			}
			wsinput.spanY = Math.abs(Double.parseDouble(spanY));
		}

		if ((wsinput.spanX > 0 && wsinput.spanY == 0) || (wsinput.spanY > 0 && wsinput.spanX == 0)) {
			throw new IllegalArgumentException("Invalid Parameter: 'spany' or 'spanx' not set.");
		}
		return wsinput;
	}

	// http://geolessiprovider.appspot.com/geths?x=9.253851&y=48.731016&r=1001
	// http://geolessiprovider.appspot.com/geths?x=9.254514&y=48.730956&spanx=0.010784&&spany=0.010298

	private void doService(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

		try {

			WSInput parseInput = parseInput(request);

			HalteStellenGetterFacadeI halteStellenInfoProvider = InfoProvider
					.getHalteStellenInfoProvider(HALTESTELLENINFOPROVIDER.BAHN);

			HalteStellenListe halteStellen = null;
			if (parseInput.radius > 0) {
				halteStellen = halteStellenInfoProvider.getHalteStellen(parseInput.coord, parseInput.radius, parseInput.hstype);
			} else {
				halteStellen = halteStellenInfoProvider.getHalteStellen(parseInput.coord, parseInput.spanX, parseInput.spanY,
						parseInput.hstype);

			}

			writeRet(request, response, halteStellen);

		} catch (Throwable e) {
			WSErrorJs wse = new WSErrorJs();
			wse.error = e.getMessage();
			writeRet(request, response, wse);
			log.error("Fehler bei Ausfuehrung des Request:" + e.getMessage());
		}
	}

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doService(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doService(request, response);
	}

	// public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
	//
	// /*
	// * http://geolessiprovider.appspot.com/t2
	// */
	// try {
	// MemcacheService syncCache = MemcacheServiceFactory.getMemcacheService();
	// // syncCache.setNamespace("d");
	// // syncCache.setErrorHandler(ErrorHandlers.getConsistentLogAndContinue(Level.INFO));
	//
	// syncCache.put("d", "oliver");
	//
	// Object object = syncCache.get("d");
	//
	// Log log = LogFactory.getLog(T2Servlet.class);
	//
	// log.error("error");
	// log.warn("warning");
	// log.info("info");
	// log.debug("debug");
	// log.fatal("fatal");
	//
	// resp.setContentType("text/plain");
	// resp.getWriter().println("Hello, world1:" + object);
	// } catch (Throwable w) {
	// resp.setContentType("text/plain");
	// resp.getWriter().println("Hello, world5:" + w + "::" + w.getMessage());
	// }
	//
	// }

	private void writeRet(HttpServletRequest pRequest, HttpServletResponse pResponse, Object pRes) {
		if (pRes == null) {
			WSErrorJs wse = new WSErrorJs();
			wse.error = "Argument to writeRet == <null>";
			pRes = wse;
		}

		try {
			OutputStream lOutputStream = (OutputStream) pResponse.getOutputStream();
			pResponse.setHeader("Content-Type", "application/json; charset=utf-8");
			pResponse.setCharacterEncoding(de.xelerity.geolessi.preferences.Preferences.ENC_UTF);
			ObjectMapper om = new ObjectMapper();

			if (lOutputStream != null) {
				om.writeValue(lOutputStream, pRes);
				lOutputStream.flush();
				lOutputStream.close();
			}

			HttpSession lSession = pRequest.getSession(false);
			if (lSession != null) {
				lSession.invalidate();
			}
		} catch (Throwable e) {
			log.error("Fehler beim Schreiben des OutputStreams:" + e.getMessage());
		}
	}

	public static void main(String[] args) {

		String spanX = "-0.23";
		if (!spanX.trim().matches("^(\\+|-)?[0-9]+(\\.[0-9]+)?"))
			System.err.println("NEEEEEEEEEEEEEIN");
		else
			System.out.println("passt:" + Double.parseDouble(spanX));

	}

}
